package loveqq.niceexcel.util;

import loveqq.niceexcel.core.metadata.DateTimeFormatData;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static loveqq.niceexcel.constant.FormatConsts.DATE_TIME_FORMAT;


/**
 * @author zhongjh@tsintergy.com
 * @date 2022-08-26
 */
public class DateUtils {
    private static final ThreadLocal<Map<String, DateFormat>> DATE_FORMAT_THREAD_LOCAL = new ThreadLocal<>();
    private static final ThreadLocal<Map<String, DateTimeFormatter>> DATE_TIME_FORMATTER_THREAD_LOCAL = new ThreadLocal<>();

    public static String format(Date value, DateTimeFormatData data) {
        String format = (data != null) ? data.getFormat() : DATE_TIME_FORMAT;
        return getCacheDateFormat(format).format(value);
    }

    public static String format(LocalDateTime value, DateTimeFormatData data) {
        String format = (data != null) ? data.getFormat() : DATE_TIME_FORMAT;
        return value.format(getCacheDateTimeFormatter(format));
    }

    public static Date parseDate(String value, DateTimeFormatData data) throws ParseException {
        String format = (data != null) ? data.getFormat() : DATE_TIME_FORMAT;
        return getCacheDateFormat(format).parse(value);
    }

    public static LocalDateTime parseLocalDateTime(String value, DateTimeFormatData data) {
        String format = (data != null) ? data.getFormat() : DATE_TIME_FORMAT;
        return LocalDateTime.parse(value, getCacheDateTimeFormatter(format));
    }


    private static DateFormat getCacheDateFormat(String format) {
        Map<String, DateFormat> cache = DATE_FORMAT_THREAD_LOCAL.get();
        if (cache == null) {
            cache = new HashMap<>();
            DATE_FORMAT_THREAD_LOCAL.set(cache);
        }
        return cache.computeIfAbsent(format, key -> new SimpleDateFormat(format));
    }

    private static DateTimeFormatter getCacheDateTimeFormatter(String format) {
        Map<String, DateTimeFormatter> cache = DATE_TIME_FORMATTER_THREAD_LOCAL.get();
        if (cache == null) {
            cache = new HashMap<>();
            DATE_TIME_FORMATTER_THREAD_LOCAL.set(cache);
        }
        return cache.computeIfAbsent(format, key -> DateTimeFormatter.ofPattern(format));
    }

    public static void removeThreadLocalCache() {
        DATE_FORMAT_THREAD_LOCAL.remove();
        DATE_TIME_FORMATTER_THREAD_LOCAL.remove();
    }

}
